﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Common.Logging;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
using SupportLibrary.Message;


namespace SupportLibrary.WebMethod
{
  
   public class SeleniumWebmethod:IWebmethod
    {
       private static ILog log = LogManager.GetLogger(typeof(SeleniumWebmethod));

       IWebDriver driver;
       public SeleniumWebmethod(string defaultBrowser)
       {
           switch (defaultBrowser)
           {
               default: driver = new FirefoxDriver(); break;

           }

       }

        ~SeleniumWebmethod()
       {
           if (driver != null)
           {
               driver.Close();
           }
           //iwebele.

       }
      
        public bool NavigateUrl(string pageurl)
        {
            try
            {

                driver.Navigate().GoToUrl(pageurl);
                return true;

            }
            catch (Exception ex)
            {
                log.Debug(pageurl + Resources.ErrorMessage.NavigatePageError + ex.Message);
                return false;
            }
        }

        public Boolean Click(string target)
        {
            
                IWebElement element = GetElement(target);
                if (element != null)
                {
                    element.Click();
                    return true;
                }
                else {
                    log.Debug(target + Resources.ErrorMessage.ClickError);
                    return false;
                }
           
                
                        
           
        }

        public bool Clear(string target)
        {
           
                IWebElement element = GetElement(target);
                if (element != null)
                {
                    element.Clear();
                    return true;
                }
                else
                {
                    log.Debug(target + Resources.ErrorMessage.ClearTextError);
                    return false;
                }
            }

        public bool SendKey(string target,string text)
        {
            IWebElement element = GetElement(target);
            if (element != null)
            {
                element.SendKeys(text);
                return true;
            }
            else
            {
                log.Debug(target + Resources.ErrorMessage.SendKeyError);
                return false;
            }
        }

        public bool SelectByText(string target,string text)
        {
            IWebElement element = GetElement(target);
            if (element != null)
            {
                try
                {
                    new SelectElement(element).SelectByText(text);
                    return true;
                }
                catch (Exception e)
                {
                    log.Debug(target + Resources.ErrorMessage.SelectByTextError + text + e.Message);
                    return false;
                }
            }
            else
            {
                log.Debug(target + Resources.ErrorMessage.SelectByTextError + text);
                return false;
            }
        }

        public bool SelectByIndex(string target,string index)
        {
            IWebElement element = GetElement(target);
            if (element != null)
            {
                try
                {
                    new SelectElement(element).SelectByIndex(int.Parse(index));
                    return true;
                }
                catch (Exception e)
                {
                    log.Debug(target + Resources.ErrorMessage.SelectByIndexError + index + e.Message);
                    return false;
                }
            }
            else
            {
                log.Debug(target + Resources.ErrorMessage.SelectByIndexError + index);
                return false;
            }
        }

        public bool SelectByValue(string target,string value)
        {
            IWebElement element = GetElement(target);
            if (element != null)
            {
                try
                {
                    new SelectElement(element).SelectByValue(value);
                    return true;
                }
                catch (Exception e)
                {
                    log.Debug(target + Resources.ErrorMessage.SelectByValueError + value + e.Message);
                    return false;
                }
            }
            else
            {
                log.Debug(target + Resources.ErrorMessage.SelectByValueError + value);
                return false;
            }
        }


        public IWebElement IsElementPresent(By by)
        {
            try
            {
                IWebElement e = driver.FindElement(by);

                return e;
            }
            catch (NoSuchElementException)
            {
                return null;
            }
        }

        public IWebElement GetElement(string target)
        {
            
            
                return WaitForElement(target);
            
        }

        
        public IWebElement WaitForElement(string target)
        {
            By by = ParseTarget(target);

            int num = 0;
            while (true)
            {
                Thread.Sleep(1000);
                num++;
                IWebElement element = IsElementPresent(by);
                if (element!=null || num == 90)
                    return element;
            }

            return null;
        }

        private By ParseTarget(string target)
        {
            try
            {
                int signal = target.IndexOf("//");

                Console.WriteLine("input string:" + target);
                if (signal == 0)
                {
                    //Console.WriteLine("xpath :" + target);
                    return By.XPath(target.Trim());
                }

                signal = target.IndexOf("name");
                if (signal == 0)
                {
                    string[] targetvalues = target.Split('=');
                    if (targetvalues.Length == 2)
                    {
                        //Console.WriteLine("name :" + targetvalues[1]);
                        return By.Name(targetvalues[1].Trim());
                    }

                }

                signal = target.IndexOf("css");

                if (signal == 0)
                {
                    string[] targetvalues = target.Split('=');
                    if (targetvalues.Length == 2)
                    {
                        //Console.WriteLine("css :" + targetvalues[1]);
                        return By.CssSelector(targetvalues[1].Trim());

                    }
                }

                signal = target.IndexOf("id");
                if (signal == 0)
                {

                    string[] targetvalues = target.Split('=');
                    if (targetvalues.Length == 2)
                    {
                        //Console.WriteLine("id :" + targetvalues[1]);
                        return By.Id(targetvalues[1].Trim());

                    }
                }

                signal = target.IndexOf("link");
                if (signal == 0)
                {

                    string[] targetvalues = target.Split('=');
                    if (targetvalues.Length == 2)
                    {
                        //Console.WriteLine("id :" + targetvalues[1]);
                        return By.LinkText(targetvalues[1].Trim());

                    }
                }

              
                //in case of list attributes

            }
            catch (Exception ex)
            {
                log.Debug(target + Resources.ErrorMessage.ParseTargetError + ex.Message);

            }
            return null;
        }

        

        public List<String> GetListElementAttributeByTagName(string pageUrl,string tagName)
        {
            List<String> attributes = new List<string>();
            try
            {
                

                driver.Navigate().GoToUrl(pageUrl);

                Dictionary<string, string> listTags = WebResource.Tags();
                    //Console.WriteLine(tag.Key + ":" + tag.Value);
                    IList<IWebElement> list = driver.FindElements(By.TagName(tagName));
                    List<string> attrs = WebResource.Attributes(listTags[tagName]);
                    for (int i = 0; i < list.Count; i++)
                    {
                        String attribuitevalue = String.Empty;
                        foreach (string attr in attrs)
                        {
                            if(!String.IsNullOrWhiteSpace(list[i].GetAttribute(attr)))
                                attribuitevalue += attr + "="+ list[i].GetAttribute(attr)+",";
                            
                        }
                        if (!String.IsNullOrWhiteSpace(attribuitevalue))
                            attributes.Add(attribuitevalue);
                    }

               
            }
            catch (Exception e)
            {
                log.Debug("Get attributes error");
            }

            return attributes;
        }


        public List<string> GetListElementAttributeAtCurrentPage(string tagName)
        {
            List<String> attributes = new List<string>();
            try
            {


                //driver.Navigate().GoToUrl(pageUrl);

                Dictionary<string, string> listTags = WebResource.Tags();
                //Console.WriteLine(tag.Key + ":" + tag.Value);
                IList<IWebElement> list = driver.FindElements(By.TagName(tagName));
                List<string> attrs = WebResource.Attributes(listTags[tagName]);
                for (int i = 0; i < list.Count; i++)
                {
                    String attribuitevalue = String.Empty;
                    foreach (string attr in attrs)
                    {
                        if (!String.IsNullOrWhiteSpace(list[i].GetAttribute(attr)))
                            attribuitevalue += attr + "=" + list[i].GetAttribute(attr) + ",";

                    }
                    if (!String.IsNullOrWhiteSpace(attribuitevalue))
                        attributes.Add(attribuitevalue);
                }


            }
            catch (Exception e)
            {
                log.Debug("Get attributes error");
            }

            return attributes;
        }


        public string CurrentUrl()
        {
            return driver.Url;
        }
    }
}
